import pylab as p 
import filter as f
import constants as c

#------------------------------------------------
# Logging
#------------------------------------------------
def Log(msg, always):
    if (c.LOG_ENABLED == 1):
        if (always == 1):
            print msg
        else:
            if(c.DEBUG_LOG == 1):
                print msg

#------------------------------------------------
# Compensar con la demora del filtro
#------------------------------------------------  
def shiftArray(limits, shift):
    for i in xrange(len(limits)):
        limits[i][0] += shift
        limits[i][1] += shift
    
    return limits

#------------------------------------------------
# Realizar Overlap and Add por convolucion
#------------------------------------------------ 
def filterSignalConvolution(filter_coef, segment, segment_index, trailing, segment_count):
    # Ancho del filtro FIR
    M_WIDTH = len(filter_coef)
    L_WIDTH = len(segment)

    Log("----Realizando filtrado por convolucion...", 0)
    filtered_segment = p.convolve(segment, filter_coef)
          
    # No sumar para primer segmento
    if (segment_index > 0):
        Log("----Sumando ultima parte del segmento anterior...", 0)
        filtered_segment[0 : M_WIDTH - 1] = filtered_segment[0 : M_WIDTH - 1] + trailing[0 : M_WIDTH]
               
    # No obtener trailing para ultimo segmento
    if (segment_index < (segment_count - 1)):
        Log("----Obteniendo ultima parte del segmento...", 0)
        trailing = filtered_segment[L_WIDTH : L_WIDTH + M_WIDTH]
       
    return [filtered_segment, trailing]

#------------------------------------------------
# Realizar Overlap and Add por FFT
#------------------------------------------------
def filterSignalFFT(filter_coef, segment, segment_index, trailing, segment_count, filter_fft):
    # Ancho del filtro FIR
    M_WIDTH = len(filter_coef)
    L_WIDTH = len(segment)
    
    Log("----Realizando filtrado por FFT...", 0)
    if (filter_fft == [] or len(filter_fft) > M_WIDTH + L_WIDTH -1):
        filter_fft = p.fft(filter_coef, L_WIDTH + M_WIDTH - 1)
       
    segment_fft = p.fft(segment, L_WIDTH + M_WIDTH - 1)
    
    filtered_segment = p.real(p.ifft(filter_fft * segment_fft))
        
    # No sumar para primer segmento
    if (segment_index > 0):
        Log("----Sumando ultima parte del segmento anterior...", 0)
        filtered_segment[0 : M_WIDTH - 1] = filtered_segment[0 : M_WIDTH - 1] + trailing[0 : M_WIDTH]
        
    # No obtener trailing para ultimo segmento
    if (segment_index < (segment_count - 1)):
        Log("----Obteniendo ultima parte del segmento...", 0)
        trailing = filtered_segment[L_WIDTH : L_WIDTH + M_WIDTH]
                   
    return [filtered_segment, trailing, filter_fft]


#------------------------------------------------
# Mostrar el filtro IIR de Butterworth
#------------------------------------------------    
def showIIRFilter(Fs, FPass, FStop, GPass, GStop, Figure=1):
    Log("Mostrando filtro Butterworth...", 0)
    B, A = f.createIIRButterFilter(Fs, FPass, FStop, GPass, GStop)
    p.figure(Figure)
    p.clf()
    ax1 = p.subplot(211)
    f.plotMagnitudeResponse('Butterworth', B, A, Fs)
    p.subplot(212, sharex=ax1)
    f.plotPhaseResponse('Butterworth', B, A, Fs)
    p.subplots_adjust(hspace=0.5)
    
    p.figure(Figure + 1)
    p.clf()
    f.plotZeroesAndPoles('Butterworth', B, A)
    
    p.figure(Figure + 2)
    p.clf()
    f.plotGroupDelay('Butterworth', B, A, Fs)
    
#------------------------------------------------
# Mostrar el filtro FIR utilizado
#------------------------------------------------  
def showFIRFilter(Fs, filter_coef, Figure=1):
    Log("Mostrando filtro FIR...", 0)
    p.figure(Figure)
    p.clf()
    ax1 = p.subplot(211)
    f.plotMagnitudeResponse('FIR', filter_coef, Fs=Fs)
    p.subplot(212, sharex=ax1)
    f.plotPhaseResponse('FIR', filter_coef, Fs=Fs)
    p.subplots_adjust(hspace=0.5)
    
    p.figure(Figure + 1)
    p.clf()
    f.plotZeroesAndPoles('FIR', filter_coef)
    
    p.figure(Figure + 2)
    p.clf()
    f.plotGroupDelay('FIR', filter_coef, Fs=Fs)
        
    p.figure(Figure + 3)
    p.clf()
    f.plotImpulseResponse('FIR', filter_coef)
    f.plotStepResponse('FIR', filter_coef)

#------------------------------------------------
# Mostrar los graficos de antes y despues
#------------------------------------------------  
def showOutput(data_original, data, fs, Figure=1):
    # Rango de tiempos para ploteo
    time_scale = p.arange(0, len(data_original) / float(fs) , 1.0 / fs)
    
    Log("Graficando datos original...", 1)
    p.figure(Figure)
    p.clf()
    ax1 = p.subplot(211)
    p.title('Senal original')
    p.plot(time_scale, data_original)
    p.ylabel('Amplitud')
    p.xlabel('Tiempo(s)')
    p.ylim(-20000, 25000)
    p.subplot(212, sharex=ax1)
    p.title('Espectrograma original')
    p.specgram(data_original, Fs=fs)
    p.ylabel('Frecuencia(Hz)')
    p.xlabel('Tiempo(s)')
    if c.PLOT_COLORBAR:
        p.colorbar()
    
    Log("Graficando datos modificada...", 1)
    p.figure(Figure + 1)
    p.clf()
    ax2 = p.subplot(211)
    p.title('Senal modificada')
    p.plot(time_scale, data)
    p.ylabel('Amplitud')
    p.xlabel('Tiempo(s)')
    p.ylim(-20000, 25000)
    p.subplot(212, sharex=ax2)
    p.title('Espectrograma modificado')
    p.specgram(data, Fs=fs)
    p.ylabel('Frecuencia(Hz)')
    p.xlabel('Tiempo(s)')
    if c.PLOT_COLORBAR:
        p.colorbar()

#------------------------------------------------
# Mostrar las dos seniales en un mismo grafico
#------------------------------------------------
def showOutputComparison(data_original, data, fs, Figure=1):
    # Rango de tiempos para ploteo
    time_scale = p.arange(0, len(data_original) / float(fs) , 1.0 / fs)
    
    Log("Graficando datos comparados...", 1)
    p.figure(Figure)
    p.clf()
    p.plot(time_scale, data_original)
    p.plot(time_scale, data)
    p.ylabel('Amplitud')
    p.xlabel('Tiempo(s)')

#------------------------------------------------
# Mostrar los graficos de antes y despues
#------------------------------------------------  
def showFilterOutput(filtered_signal, fs, Figure=1):
    # Rango de tiempos para ploteo
    time_scale = p.arange(0, len(filtered_signal) / float(fs) , 1.0 / fs)

    Log("Graficando el espectro de la salida del filtro...", 1)
    p.figure(Figure)
    p.clf()
    ax1 = p.subplot(211)
    p.title('Senal')
    p.plot(time_scale, filtered_signal)
    p.ylabel('Amplitud')
    p.xlabel('Tiempo(s)')
    p.axhline(y=c.WAVE_THRESHOLD, linewidth=2, color='r')
    p.axhline(y= -c.WAVE_THRESHOLD, linewidth=2, color='r')
    p.subplot(212, sharex=ax1)
    p.title('Espectrograma')
    p.ylabel('Frecuencia(Hz)')
    p.xlabel('Tiempo(s)')
    p.specgram(filtered_signal, Fs=fs)
    
#------------------------------------------------
# Mostrar los clicks detectados en cada iteracion
#------------------------------------------------
def showIterationResults(data_original, data, fs, template_limits, Figure=1):
    # Rango de tiempos para ploteo
    time_scale = p.arange(0, len(data_original) / float(fs) , 1.0 / fs)
    
    p.figure(Figure)
    p.clf()
    ax1 = p.subplot(211)
    p.title('Senal original')
    p.plot(time_scale, data_original)
    p.ylabel('Amplitud')
    p.xlabel('Tiempo(s)')    
    for i in xrange(len(template_limits)):
        original = template_limits[i]
        sub_scale_ori = time_scale[original[0]: original[1]]
        sub_original = data_original[original[0]: original[1]]
        p.plot(sub_scale_ori, sub_original, 'r')
        
    p.subplot(212, sharex=ax1)
    p.title('Espectrograma original')
    p.ylabel('Frecuencia(Hz)')
    p.xlabel('Tiempo(s)')
    p.specgram(data_original, Fs=fs)
    
    p.figure(Figure + 1)
    p.clf()
    ax2 = p.subplot(211)
    p.title('Senal modificada')
    p.plot(time_scale, data)
    p.ylabel('Amplitud')
    p.xlabel('Tiempo(s)')
    for i in xrange(len(template_limits)):
        original = template_limits[i]
        sub_scale_ori = time_scale[original[0]: original[1]]
        sub_original = data[original[0]: original[1]]
        p.plot(sub_scale_ori, sub_original, 'r')
        
    p.subplot(212, sharex=ax2)
    p.title('Espectrograma modificado')
    p.ylabel('Frecuencia(Hz)')
    p.xlabel('Tiempo(s)')
    p.specgram(data, Fs=fs)

    
def showSmoothingWindow(Figure=1): 
    p.figure(Figure)
    p.clf()
    p.title('Ventana de empalme')
    x = p.arange(0, len(c.WINDOW))
    p.stem(x, c.WINDOW)
    p.ylabel('Amplitud')
    p.xlabel('n')
    p.plot()
